/*
 * $Id: MainApp.h 396 2010-10-01 13:09:39Z chunghh $
 */

#ifndef _MAINAPP_CLASS_
#define _MAINAPP_CLASS_

#include <xp/sys/Daemon.hpp>
#include <xp/bas/Mutex.hpp>
#include "TcpGate.h"
#include "AppEnv.h"

class MainApp: public xp::sys::UnpausableDaemon
{
public:
	friend class AppEnv;

	MainApp ();
	virtual ~MainApp ();

	int run ();

	int stop ();
	int shutdown ();

	int stopWithCode (int code);

	void handleSignal (int sig);

	void setMaxTcpGateConnections (unsigned int max)
	{
		tcpgate.thread.setMaxConnections (max);
	}

	void forceTcpGateService (const xp_char_t* str)
	{
		if (str) 
		{
			xp_strxcpy (tcpgate.forced_service, 
				xp_countof(tcpgate.forced_service), str);
		}
		else tcpgate.forced_service[0] = XP_T('\0');
	}	

	void setSysconfDir (const xp_char_t* dir);

	int writeEnvToFile ()
	{
		return this->env.file.write (&this->env.data);
	}

protected:
	bool stop_requested;
	int ret_code;

	xp_pid_t parent_pid;
	xp_pid_t nanny_pid;
	xp_pid_t child_pid;

public:
	struct
	{
		Mutex      mutex;
		AppEnv     data;
		AppEnvPath file;
	} env;

protected:
	struct tcpgate_t
	{
		tcpgate_t (const xp_char_t* name): thread (name) {}
		Mutex     startup_mutex;
		TcpGate   thread;
		xp_char_t forced_service[TcpAddress::MAX_SERVICE_LEN+1];
	} tcpgate;

	void setup_signal_handlers ();
	void restore_signal_handlers ();

	int  run_nanny ();
	int  run_main_task ();
	void load_env_file ();

	int process_system_config ();
	int run_tcp_gate_thread ();
};

#endif
